import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class TimeMethodInterceptor implements MethodInterceptor {
    /**
     * Object obj：        代理对象，即目标对象的子类
     * <p>
     * Method method：     目标类的方法对象，通过这个对象可以获得目标类中这个方法的详细信息，如方法名、参数类型、返回类型等
     * <p>
     * Object[] args：     代理对象重载父类方法后的代理对象的方法相关参数列表。这个数组包含了在方法调用时传递的实际参数
     * <p>
     * MethodProxy proxy： 这是CGLIB生成代理对象同时生成的另外一个对象，它用于调用原始父类对象（目标对象）的方法。
     * CGLIB 会为目标类中的每一个非 final 方法生成一个对应的 MethodProxy 对象，通过这个对象，可以在 intercept 方法中调用原始方法的实现。
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        // 前面增强
        long start = System.currentTimeMillis();

        // 原业务
        Object result = methodProxy.invokeSuper(obj, objects);

        // 这里一定不能写method.invoke(obj, objects)
        // obj是代理对象，这么调用会再起调起代理对象的方法，然后被CGLIB拦截器拦截，再重复调用，直到栈溢出

        // 后面增强
        long end = System.currentTimeMillis();
        System.out.println("耗时" + (end - start) + "ms");

        return result;
    }
}
